package models

import (
	"context"
	"go-chain-api/global"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo/options"
	"time"
)

type ChainApply struct {
	Id             string `bson:"_id,omitempty" json:"id"`
	ChainConfigId0 string `bson:"chainConfigId0" json:"chainConfigId0"`
	ChainConfigId1 string `bson:"chainConfigId1" json:"chainConfigId1"`
	TokenId0       string `bson:"tokenId0" json:"tokenId0"`
	TokenId1       string `bson:"tokenId1" json:"tokenId1"`
	TxHash         string `bson:"txHash" json:"txHash"`
	From           string `bson:"from" json:"from"`
	To             string `bson:"to" json:"to"`
	Status         string `bson:"status" json:"status"`
	UserId         string `bson:"userId" json:"userId"`
	Amount0        string `bson:"amount0" json:"amount0"`
	Amount1        string `bson:"amount1" json:"amount1"`
	TimeStamp      int64  `bson:"timeStamp" json:"timeStamp"`
}

//type RequestData struct {
//	ChainConfigId0 string
//	ChainConfigId1 string
//	TokenId0       string
//	TokenId1       string
//	TxHash         string
//	From           string
//	To             string
//	UserId         string
//	Amount0        string
//	Amount1        string
//}

type ResponseData struct {
	ChainName0 string `json:"chainName0"`
	ChainName1 string `json:"chainName1"`
	Status     string `json:"status"`
	TokenName0 string `json:"tokenName0"`
	TokenName1 string `json:"tokenName1"`
	TimeStamp  string `json:"timeStamp"`
	Amount0    string `json:"amount0"`
	Amount1    string `json:"amount1"`
}

func (a ChainApply) Create(c ChainApply) error {
	model := new(ChainApply)
	model.ChainConfigId0 = c.ChainConfigId0
	model.ChainConfigId1 = c.ChainConfigId1
	model.TokenId0 = c.TokenId0
	model.TokenId1 = c.TokenId1
	model.TxHash = c.TxHash
	model.From = c.From
	model.To = c.To
	model.UserId = c.UserId
	model.Status = "0"
	model.Amount0 = c.Amount0
	model.Amount1 = c.Amount1
	model.TimeStamp = time.Now().Unix()
	//err := model.Create(s.db.GetDb())
	//cfg := configs.Get().Mongodb
	//applyClient := client.Database(cfg.Config.Name).Collection("chain_apply")
	//_, err := applyClient.InsertOne(context.TODO(), c)
	applyClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("chain_apply")
	_, err := applyClient.InsertOne(context.TODO(), model)
	if err != nil {
		return err
	}

	return err
}

func (a ChainApply) List(userId string, from string, pageIndex uint, pageSize uint) (chainApplyTotal int64, chainApplyList []ResponseData, err error) {

	model := new(ChainApply)
	model.UserId = userId
	model.From = from
	total, err := model.Count()
	list, err := model.Listv1(pageIndex, pageSize)
	//cfg := configs.Get().Mongodb
	chainConfigClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("chain_config")
	chainTokenClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("chain_token")

	var responseList []ResponseData

	var chainConfig struct {
		ChainName string `bson:"chainName"`
	}
	var chainToken struct {
		Symbol string `bson:"symbol"`
	}

	loc, _ := time.LoadLocation("Asia/Shanghai")
	for _, apply := range list {
		var data ResponseData
		configId0, _ := primitive.ObjectIDFromHex(apply.ChainConfigId0)
		configId1, _ := primitive.ObjectIDFromHex(apply.ChainConfigId1)
		tokenId0, _ := primitive.ObjectIDFromHex(apply.TokenId0)
		tokenId1, _ := primitive.ObjectIDFromHex(apply.TokenId1)
		_ = chainConfigClient.FindOne(context.TODO(), bson.D{{"_id", configId0}}).Decode(&chainConfig)
		data.ChainName0 = chainConfig.ChainName
		_ = chainConfigClient.FindOne(context.TODO(), bson.D{{"_id", configId1}}).Decode(&chainConfig)
		data.ChainName1 = chainConfig.ChainName
		_ = chainTokenClient.FindOne(context.TODO(), bson.D{{"_id", tokenId0}}).Decode(&chainToken)
		data.TokenName0 = chainToken.Symbol
		_ = chainTokenClient.FindOne(context.TODO(), bson.D{{"_id", tokenId1}}).Decode(&chainToken)
		data.TokenName1 = chainToken.Symbol
		data.Status = apply.Status
		data.Amount0 = apply.Amount0
		data.Amount1 = apply.Amount1
		data.TimeStamp = time.Unix(apply.TimeStamp, 0).In(loc).Format("2006-01-02 15:04:05")
		responseList = append(responseList, data)
	}
	return total, responseList, err
}

func (c *ChainApply) Listv1(pageIndex uint, pageSize uint) ([]ChainApply, error) {

	//cfg := configs.Get().Mongodb
	var chainApplyList []ChainApply
	applyClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("chain_apply")
	// 根据userId和from查询 并且根据时间倒序排 并p分页
	findOptions := options.Find()
	findOptions.SetSort(bson.D{{"timeStamp", -1}})
	findOptions.SetSkip(int64((pageIndex - 1) * pageSize))
	findOptions.SetLimit(int64(pageSize))

	find, err := applyClient.Find(context.TODO(), bson.D{{"userId", c.UserId}, {"from", c.From}}, findOptions)
	if err != nil {
		return nil, err
	}
	err = find.All(context.TODO(), &chainApplyList)
	if err != nil {
		return nil, err
	}

	return chainApplyList, nil
}

func (c *ChainApply) Count() (int64, error) {
	//cfg := configs.Get().Mongodb
	applyClient := global.DBEngine.Database(global.DbConfig.DbName).Collection("chain_apply")
	count, err := applyClient.CountDocuments(context.TODO(), bson.D{{"userId", c.UserId}, {"from", c.From}})
	if err != nil {
		return 0, err
	}
	return count, nil
}
